﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AppEnvironment.Lib.Interfaces;
using System.IO;

namespace AppEnvironment
{
    public static class Extentions
    {
        public static T Get<T>(this IStateHolder stateHolder, string key)
        {
            return stateHolder.Get<T>(key, null);
        }

        public static T Get<T>(this IStateHolder stateHolder, string key, Func<T> initializer)
        {
            object objValue = stateHolder[key];
            if ((objValue == null) && (initializer != null))
            {
                objValue = initializer();
                stateHolder[key] = objValue;
            }
            return (T)(objValue);
        }

        public static void Clear(this IStateHolder stateHolder) 
        {
            IClearable clearable = stateHolder as IClearable;
            if (clearable != null)
            {
                clearable.Clear();
            }
        }

        public static string GetUniqueId(this IStateHolder stateHolder)
        {
            IUniquelyNamed named = stateHolder as IUniquelyNamed;
            if (named != null)
            {
                return named.Id;
            }
            return "";
        }

        public static void WriteTo(this Stream source, Stream target)
        {
            WriteTo(source, target, 4096);
        }

        public static void WriteTo(this Stream source, Stream target, int bufferLength)
        {
            byte[] buffer = new byte[bufferLength];
            int bytesRead = 0;

            do
            {
                bytesRead = source.Read(buffer, 0, buffer.Length);
                target.Write(buffer, 0, bytesRead);
            } while (bytesRead > 0);
        }

        public static List<T> Paginate<T>(this IEnumerable<T> source, int pageNumber, int pageSize, out bool hasMorePages)
        {
            int startRow = (pageNumber - 1) * pageSize;
            var result = (from x in source select x).Skip(startRow).Take(pageSize + 1);
            List<T> list = result.ToList();
            hasMorePages = list.Count > pageSize;
            if (hasMorePages)
            {
                list.RemoveAt(list.Count - 1);
            }
            return list;
        }

        public static System.Collections.ObjectModel.Collection<T> ToCollection<T>(this IEnumerable<T> self)
        {
            System.Collections.ObjectModel.Collection<T> result = new System.Collections.ObjectModel.Collection<T>();
            if (self != null)
            {
                foreach (var item in self)
                {
                    result.Add(item);
                }
            }
            return result;
        }
    }
}
